﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//using System.Drawing;
using System.IO;

namespace winForm_Bmp
{
    public partial class Form1 : Form
    {

        private Bitmap BitmapSrc = null;
        private string FilePath = null;
        private string FileName = null;
        private string TargetFilePath = null;
        private UInt32[] buffer_bits = null;
        private string string_buffer = null;

        private int bmp_pixel_wide;
        private int bmp_pixel_height;

        public Form1(String[] args)
        {
            InitializeComponent();

            if (args != null)
            {
                foreach (string s in args)
                {

                    int index = s.LastIndexOf(@"\");

                    if (index > 0)
                    {
                        FilePath = s;
                        String FileSavePath = FilePath.Substring(0, index);
                        String SourceFileName = FilePath.Substring(index + 1, FilePath.Length - index - 1);
                        FileName = SourceFileName.Substring(0, SourceFileName.Length - 4);
                        TargetFilePath = FileSavePath + @"\" + FileName + @".c";

                        filepath_check_bmp_input();
                        save_to_file();
                    }
                }
            }

        }

        /// <summary>
        /// 保存数据、高位优先 低位自动填0
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        private UInt32[] bmp_2_string(Bitmap bmp)
        {
            int height = bmp.Height;
            UInt32[] bmp_int_buffer = null;

            bmp_pixel_height = height;
            bmp_pixel_wide = bmp.Width;

            if (height <= 32)
            {
                bmp_int_buffer = new UInt32[bmp_pixel_wide];
            }
            else
            {
                Console.WriteLine("just support the height less than 32 ");
                return null;
            }


            for (int i = 0; i < bmp_pixel_wide; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    Color srcColor = bmp.GetPixel(i, j);

                    int rgb = srcColor.R + srcColor.G + srcColor.B;

                    if (rgb <= 256 * 3 / 2)
                    {
                        bmp_int_buffer[i] &= ~((UInt32)1 << (31 - j));
                    }
                    else
                    {
                        bmp_int_buffer[i] |= ((UInt32)1 << (31 - j));
                    }
                }
            }
            return bmp_int_buffer;
        }



        private string u32_to_stream(UInt32[] data, int height = 32)
        {
            string s = "";
            string SaveingTypeString = "uint32_t";
            int IntMoveRightCtrlCnt = 0;
            int PadLeftCtrlCnt = 8;


            if (height == 8)
            {
                SaveingTypeString = "uint8_t";
                IntMoveRightCtrlCnt = 24;
                PadLeftCtrlCnt = 2;
            }
            else if (height == 16)
            {
                SaveingTypeString = "uint16_t";
                IntMoveRightCtrlCnt = 16;
                PadLeftCtrlCnt = 4;
            }
            //else if (height == 24)
            //{
            //    SaveingTypeString = "uint32_t";
            //    IntMoveRightCtrlCnt = 8;
            //    PadLeftCtrlCnt = 6;
            //}
            else
            {
                //defalt_params
                SaveingTypeString = "uint32_t";
                IntMoveRightCtrlCnt = 0;
                PadLeftCtrlCnt = 8;
            }

            s += "static const "+ SaveingTypeString + " src_" + FileName + "[] = {";

            for (int i = 0; i < bmp_pixel_wide; i++)
            {
                if (i % 4 == 0)
                {
                    s += "\r\n";
                }

                uint TargetValue = data[i] >> IntMoveRightCtrlCnt;

                string int2string = string.Format("{0:X}", TargetValue);
                int2string = int2string.PadLeft(PadLeftCtrlCnt, '0');
                int2string = "0x" + int2string + ",";

                s += int2string;
            }

            s += "\r\n};\r\n";
            return s;
        }

        private void filepath_check_bmp_input()
        {
            txBoxFilePath.Text = FilePath.ToString();
            BitmapSrc = (Bitmap)Bitmap.FromFile(FilePath);
            buffer_bits = bmp_2_string(BitmapSrc);
            picBox.Width = bmp_pixel_wide;
            picBox.Image = Image.FromFile(FilePath);
            string_buffer = u32_to_stream(buffer_bits, bmp_pixel_height);
        }

        private void bt_File_Click(object sender, EventArgs e)
        {
            OpenFileDialog bmpDialog = new OpenFileDialog();
            bmpDialog.Title = "选择bmp";
            bmpDialog.InitialDirectory = "";
            bmpDialog.Filter = "jpg(*.jpg)|*.jpg|bmp(*.bmp)|*.bmp|All files (*.*)|*.*";
            bmpDialog.FilterIndex = 0;
            if (bmpDialog.ShowDialog() == DialogResult.OK)
            {
                FilePath = bmpDialog.FileName;

                int index = FilePath.LastIndexOf(@"\");
                if (index > 0)
                {
                    String FileSavePath = FilePath.Substring(0, index);
                    String SourceFileName = FilePath.Substring(index + 1, FilePath.Length - index - 1);
                    FileName = SourceFileName.Substring(0, SourceFileName.Length - 4);
                    TargetFilePath = FileSavePath + @"\" + FileName + @".c";
                }

                filepath_check_bmp_input();
            }
        }

        private void save_to_file()
        {
            if (File.Exists(TargetFilePath))
            {
                File.Delete(TargetFilePath);
            }
            else
            {
                //File.Create(TargetFilePath);
            }
            FileStream fs = new FileStream(TargetFilePath, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            sw.Write(string_buffer);
            sw.Close();
            fs.Close();
        }
        private void bt_Start_Click(object sender, EventArgs e)
        {
            SaveFileDialog FileSaving = new SaveFileDialog();
            FileSaving.Filter = "*.c|*.c";
            FileSaving.FilterIndex = 1;
            FileSaving.FileName = FileName;
            
            if (DialogResult.OK == FileSaving.ShowDialog())
            {

                TargetFilePath = FileSaving.FileName;
                save_to_file();
            }

        }
    }
}
